from flask import Flask, request, Response, redirect, jsonify
from werkzeug.wrappers import Request
import jwt
from config import SECRET_KEY
from common.json_response import JsonResponse
from common.status_code import StatusCode
from datetime import datetime
import os
import json
import threading
from config import EXEMPT_PATHS
from common.logger import logger


class AuthenticationMiddleware:
    def __init__(self, app):
        self.app = app
        self.exempt_paths = EXEMPT_PATHS

    def __call__(self, environ, start_response):
        request_obj = Request(environ)
        path = request_obj.path

        if path in self.exempt_paths or any(path.startswith(p) for p in self.exempt_paths):
            return self.app(environ, start_response)

        auth_result = self.check_auth(request_obj)
        if not auth_result['authenticated']:
            # if request_obj.headers.get('X-Requested-With') == 'XMLHttpRequest':
                # API请求返回JSON响应
            response = JsonResponse.error(
                message=auth_result['message'],
                status=StatusCode.UNAUTHORIZED.value
            )
            return response(environ, start_response)
            # else:
            #     # 普通请求重定向到登录页
            #     start_response('302 Found', [('Location', '/login')])
            #     return [b'']

        return self.app(environ, start_response)

    def check_auth(self, request):
        token = request.cookies.get('user_token')
        if not token:
            return {
                'authenticated': False,
                'message': '未登录'
            }

        try:
            payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
            return {
                'authenticated': True,
                'user_id': payload.get('user_id'),
                'message': '验证成功'
            }
        except jwt.ExpiredSignatureError:
            return {
                'authenticated': False,
                'message': '登录已过期'
            }
        except jwt.InvalidTokenError:
            return {
                'authenticated': False,
                'message': '无效的认证信息'
            }

    def is_authenticated(self, request):
        return self.check_auth(request)['authenticated']

class RequestLoggingMiddleware:
    def __init__(self, app):
        self.app = app
        self.log_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'log')
        if not os.path.exists(self.log_dir):
            os.makedirs(self.log_dir)
        self.lock = threading.Lock()

    def __call__(self, environ, start_response):
        request_obj = Request(environ)
        try:
            self.log_request_info(request_obj)
            return self.app(environ, start_response)
        except Exception as e:
            print(f"日志记录错误: {str(e)}")

    def write_log(self, content):
        with self.lock:
            try:
                with open(self.get_log_file(), 'a', encoding='utf-8') as f:
                    f.write(f'{content}\n')
            except Exception as e:
                print(f"写入日志错误: {str(e)}")

    def get_log_file(self):
        today = datetime.now().strftime('%Y-%m-%d')
        return os.path.join(self.log_dir, f'{today}.log')

    def log_request_info(self, request):
        log_content = {
            '请求时间': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            '请求方法': request.method,
            '请求路径': request.path,
            '请求参数': dict(request.args),
            '请求头': dict(request.headers)
        }
        logger.info(f"Request: {json.dumps(log_content, ensure_ascii=False)}")
    def log_response_info(self, status, headers):
        log_content = {
            '响应状态': status,
            '响应头': dict(headers)
        }
        logger.info(f"Response: {json.dumps(log_content, ensure_ascii=False)}")